#include "patterns.h"
#include "util.h"

// #define POS(i, j) ((i) * board_size + (j))
// #define I(pos) ((pos) / board_size)
// #define J(pos) ((pos) % board_size)

//extern int board_size;

bool T(int x, int y, int state, int* board){
	if (x>=0 && x<board_size && y>=0 && y<board_size && board[POS(x,y)]==state) return true;
	return false;
} 
bool TN(int x, int y, int state, int* board){
	if (x>=0 && x<board_size && y>=0 && y<board_size && board[POS(x,y)]!=state) return true;
	return false;
} 

bool pattern1(int x, int y, int* BD){
	if (x==0 || y==0 || x ==board_size -1 || y== board_size -1)
		return false;
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( T(x-1,y-1,B,BD) && T(x-1,y,W,BD) && T(x-1,y+1,B,BD) &&
		 T(x,y-1,E,BD) && T(x,y+1,E,BD) ) return true;
	if ( T(x-1,y-1,B,BD) && T(x-1,y,E,BD) &&
		 T(x,y-1,W,BD) &&
		 T(x+1,y-1,B,BD) && T(x+1,y,E,BD) ) return true;
	if ( T(x+1,y-1,B,BD) && T(x+1,y,W,BD) && T(x+1,y+1,B,BD) &&
		 T(x,y-1,E,BD) && T(x,y+1,E,BD) ) return true;
	if ( T(x-1,y+1,B,BD) && T(x-1,y,E,BD) &&
		 T(x,y+1,W,BD) &&
		 T(x+1,y+1,B,BD) && T(x+1,y,E,BD) ) return true;
	return false;
} 
bool pattern2(int x, int y, int* BD){
	if (x==0 || y==0 || x ==board_size -1 || y== board_size -1)
		return false;
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( T(x-1,y-1,B,BD) && T(x-1,y,W,BD) && T(x-1,y+1,E,BD) &&
		 T(x,y-1,E,BD) && T(x,y+1,E,BD) &&
		 T(x+1,y,E,BD) ) return true;
	if ( T(x-1,y-1,E,BD) && T(x-1,y,E,BD) &&
		 T(x,y-1,W,BD) && T(x,y+1,E,BD) &&
		 T(x+1,y-1,B,BD) && T(x+1,y,E,BD) ) return true;
	if ( T(x+1,y-1,E,BD) && T(x+1,y,W,BD) && T(x+1,y+1,B,BD) &&
		 T(x,y-1,E,BD) && T(x,y+1,E,BD) &&
		 T(x-1,y,E,BD) ) return true;
	if ( T(x+1,y+1,E,BD) && T(x+1,y,E,BD) &&
		 T(x,y+1,W,BD) && T(x,y-1,E,BD) &&
		 T(x-1,y+1,B,BD) && T(x-1,y,E,BD) ) return true;
	return false;
} 
bool pattern3(int x, int y, int* BD){
	if (x==0 || y==0 || x ==board_size -1 || y== board_size -1)
		return false;
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( T(x-1,y-1,B,BD) && T(x-1,y,W,BD) &&
		 T(x,y-1,B,BD) && T(x,y+1,E,BD) &&
		 T(x+1,y,E,BD) ) return true;
	if ( T(x-1,y,E,BD) &&
		 T(x,y-1,W,BD) && T(x,y+1,E,BD) &&
		 T(x+1,y-1,B,BD) && T(x+1,y,B,BD) ) return true;
	if ( T(x+1,y+1,B,BD) && T(x+1,y,W,BD) &&
		 T(x,y+1,B,BD) && T(x,y-1,E,BD) &&
		 T(x-1,y,E,BD) ) return true;
	if ( T(x+1,y,E,BD) &&
		 T(x,y+1,W,BD) && T(x,y-1,E,BD) &&
		 T(x-1,y+1,B,BD) && T(x-1,y,B,BD) ) return true;
	return false;
} 
bool pattern4(int x, int y, int* BD){
	if (x==0 || y==0 || x ==board_size -1 || y== board_size -1)
		return false;
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( T(x-1,y-1,B,BD) && T(x-1,y,W,BD) && T(x-1,y+1,W,BD) &&
		 T(x,y-1,E,BD) && T(x,y+1,E,BD) &&
		 T(x+1,y,E,BD) ) return true;
	if ( T(x-1,y-1,W,BD) && T(x-1,y,E,BD) &&
		 T(x,y-1,W,BD) && T(x,y+1,E,BD) &&
		 T(x+1,y-1,B,BD) && T(x+1,y,E,BD) ) return true;
	if ( T(x+1,y-1,W,BD) && T(x+1,y,W,BD) && T(x+1,y+1,B,BD) &&
		 T(x,y-1,E,BD) && T(x,y+1,E,BD) &&
		 T(x-1,y,E,BD) ) return true;
	if ( T(x+1,y+1,W,BD) && T(x+1,y,E,BD) &&
		 T(x,y+1,W,BD) && T(x,y-1,E,BD) &&
		 T(x-1,y+1,B,BD) && T(x-1,y,E,BD) ) return true;
	return false;
} 
bool pattern5(int x, int y, int* BD){
	if (x==0 || y==0 || x ==board_size -1 || y== board_size -1)
		return false;
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( T(x-1,y-1,B,BD) && T(x-1,y,W,BD) &&
		 T(x,y-1,W,BD) ) return true;
		 
	if ( T(x,y-1,W,BD) &&
		 T(x+1,y-1,B,BD) && T(x+1,y,W,BD) ) return true;
		 
	if ( T(x+1,y+1,B,BD) && T(x+1,y,W,BD) &&
		 T(x,y+1,W,BD) ) return true;
	
	if ( T(x,y+1,W,BD) &&
		 T(x-1,y+1,B,BD) && T(x-1,y,W,BD) ) return true;
	return false;
} 

bool pattern6(int x, int y, int* BD){
	if (x==0 || y==0 || x ==board_size -1 || y== board_size -1)
		return false;
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( T(x-1,y-1,B,BD) && T(x-1,y,W,BD) &&
		 T(x,y-1,W,BD) && T(x,y+1,W,BD) &&
		 T(x+1,y,E,BD) ) return true;
		 
	if ( T(x-1,y,W,BD) &&
		 T(x,y-1,W,BD) && T(x,y+1,E,BD) &&
		 T(x+1,y-1,B,BD) && T(x+1,y,W,BD) ) return true;
		 
	if ( T(x+1,y+1,B,BD) && T(x+1,y,W,BD) &&
		 T(x,y+1,W,BD) && T(x,y-1,W,BD) &&
		 T(x-1,y,E,BD) )return true;
	
	if ( T(x+1,y,W,BD) &&
		 T(x,y+1,W,BD) && T(x,y-1,E,BD) &&
		 T(x-1,y+1,B,BD) && T(x-1,y,W,BD) ) return true;
	return false;
} 

bool pattern7(int x, int y, int* BD){
	if (x==0 || y==0 || x ==board_size -1 || y== board_size -1)
		return false;
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( T(x-1,y-1,B,BD) && T(x-1,y,W,BD) &&
		 T(x,y-1,W,BD) && T(x,y+1,E,BD) &&
		 T(x+1,y,W,BD)) return true;
		 
	if ( T(x-1,y,E,BD) &&
		 T(x,y-1,W,BD) && T(x,y+1,W,BD) &&
		 T(x+1,y-1,B,BD) && T(x+1,y,W,BD) ) return true;
		 
	if ( T(x+1,y+1,B,BD) && T(x+1,y,W,BD) &&
		 T(x,y+1,W,BD) && T(x,y-1,E,BD) &&
		 T(x-1,y,E,BD)) return true;
	
	if ( T(x+1,y,E,BD) &&
		 T(x,y+1,W,BD) && T(x,y-1,W,BD) &&
		 T(x-1,y+1,B,BD) && T(x-1,y,W,BD) ) return true;
	return false;
} 

bool pattern8(int x, int y, int* BD){
	if (x==0 || y==0 || x ==board_size -1 || y== board_size -1)
		return false;
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( T(x-1,y,B,BD) &&
		 T(x,y-1,W,BD) && T(x,y+1,W,BD) &&
		 TN(x+1,y-1,W,BD) && TN(x+1,y,W,BD) && TN(x+1,y+1,W,BD)) return true;
		 
	if ( T(x-1,y,W,BD) && TN(x-1,y+1,W,BD) &&
		 T(x,y-1,B,BD) && TN(x,y+1,W,BD) &&
		 T(x+1,y,W,BD) && TN(x+1,y+1,W,BD) ) return true;
		 
	if ( T(x+1,y,B,BD) &&
		 T(x,y+1,W,BD) && T(x,y-1,W,BD) &&
		 TN(x-1,y+1,W,BD) && TN(x-1,y,W,BD) && TN(x-1,y-1,W,BD)) return true;
	
	if ( T(x+1,y,W,BD) && TN(x+1,y-1,W,BD) &&
		 T(x,y+1,B,BD) && TN(x,y-1,W,BD) &&
		 T(x-1,y,W,BD) && TN(x-1,y-1,W,BD) ) return true;
} 

bool pattern9(int x, int y, int* BD){
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( x==board_size-1 &&
		 T(x-1,y-1,B,BD) && T(x-1,y,E,BD) &&
		 T(x,y-1,W,BD) ) return true;
		 
	if ( y==board_size-1 &&
		 T(x,y-1,E,BD) &&
		 T(x+1,y-1,B,BD) && T(x+1,y,W,BD) ) return true;
		 
	if ( x==0 &&
		 T(x+1,y+1,B,BD) && T(x+1,y,E,BD) &&
		 T(x,y+1,W,BD) ) return true;
	
	if ( y==0 &&
		 T(x,y+1,E,BD) &&
		 T(x-1,y+1,B,BD) && T(x-1,y,W,BD) ) return true;
} 

bool pattern10(int x, int y, int* BD){
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( x==board_size-1 &&
		 T(x-1,y,B,BD) &&
		 TN(x,y-1,B,BD) && T(x,y+1,W,BD) ) return true;
		 
	if ( y==board_size-1 &&
		 T(x-1,y,W,BD) &&
		 T(x,y-1,B,BD) && 
		 TN(x+1,y,B,BD) ) return true;
		 
	if ( x==0 &&
		 T(x+1,y,B,BD) &&
		 TN(x,y+1,B,BD) && T(x,y-1,W,BD) ) return true;
	
	if ( y==0 &&
		 T(x+1,y,W,BD) &&
		 T(x,y+1,B,BD) && 
		 TN(x-1,y,B,BD) ) return true;
} 

bool pattern11(int x, int y, int* BD){
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( x==board_size-1 &&
		 T(x-1,y,B,BD) && T(x-1,y+1,W,BD) ) return true;
		 
	if ( y==board_size-1 &&
		 T(x-1,y-1,W,BD) &&
		 T(x,y-1,B,BD) ) return true;
		 
	if ( x==0 &&
		 T(x+1,y,B,BD) && T(x+1,y-1,W,BD) ) return true;
	
	if ( y==0 &&
		 T(x+1,y+1,W,BD) &&
		 T(x,y+1,B,BD) ) return true;
} 

bool pattern12(int x, int y, int* BD){
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( x==board_size-1 &&
		 T(x-1,y,B,BD) && T(x-1,y+1,W,BD) &&
		 TN(x,y+1,B,BD)) return true;
		 
	if ( y==board_size-1 &&
		 T(x-1,y-1,W,BD) && TN(x-1,y,B,BD) &&
		 T(x,y-1,B,BD) ) return true;
		 
	if ( x==0 &&
		 T(x+1,y,B,BD) && T(x+1,y-1,W,BD) &&
		 TN(x,y-1,B,BD)) return true;
	
	if ( y==0 &&
		 T(x+1,y+1,W,BD) && TN(x+1,y,B,BD) &&
		 T(x,y+1,B,BD) ) return true;
} 

bool pattern13(int x, int y, int* BD){
	int B = BLACK;
	int W = WHITE;
	int E = EMPTY;
	if ( x==board_size-1 &&
		 T(x-1,y,B,BD) && T(x-1,y+1,W,BD) &&
		 T(x,y-1,W,BD) && T(x,y+1,B,BD) ) return true;
		 
	if ( y==board_size-1 &&
		 T(x-1,y-1,W,BD) && T(x-1,y,B,BD) &&
		 T(x,y-1,B,BD) &&
		 T(x+1,y,W,BD) ) return true;
		 
	if ( x==0 &&
		 T(x+1,y,B,BD) && T(x+1,y-1,W,BD) &&
		 T(x,y+1,W,BD) && T(x,y-1,B,BD) ) return true;
	
	if ( y==0 &&
		 T(x+1,y+1,W,BD) && T(x+1,y,B,BD) &&
		 T(x,y+1,B,BD) &&
		 T(x-1,y,W,BD) ) return true;
} 



int matchpattern2(int i, int j, int color, int *board) {
    if (pattern1(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 1;
    if (pattern2(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 2;
    if (pattern3(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 3;
    if (color == BLACK && pattern4(i,j,board) && board[POS(i,j)]  == EMPTY)
        return 4;
    if (pattern5(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 5;
    if (pattern6(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 6;
    if (pattern7(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 7;
    if (pattern8(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 8;
    if (pattern9(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 9;
    if (pattern10(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 10;
    if (color == BLACK && pattern11(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 11;
    if (color == WHITE && pattern12(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 12;
    if (color == WHITE && pattern13(i,j,board)&& board[POS(i,j)]  == EMPTY)
        return 13;
    return 0;
}
